package game.common.net;

import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.channels.ClosedChannelException;

import org.xsocket.MaxReadSizeExceededException;
import org.xsocket.connection.IDataHandler;
import org.xsocket.connection.INonBlockingConnection;

public abstract class GamePacketHandler extends GameHandler implements IDataHandler{

	@Override
	public boolean onData(INonBlockingConnection nbc) throws IOException,BufferUnderflowException,ClosedChannelException,MaxReadSizeExceededException {
		nbc.markReadPosition();
		
		short packetType = nbc.readShort();
		short packetLength = nbc.readShort();
		
		// break method if not enough bytes
		if (nbc.available() < packetLength){
			nbc.resetToReadMark();
			return true;
		} else {
			return readPacket(packetType, packetLength, nbc);
		}
	}
	
	protected abstract boolean readPacket(int type, int len, INonBlockingConnection nbc) throws IOException,BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException ;

	/**
	 * @param packetType
	 * @param nbc must be autoFlush = false
	 * 
	 * @throws BufferOverflowException
	 * @throws IOException
	 */
	public void preparePacket(int packetType, INonBlockingConnection nbc) throws BufferOverflowException, IOException{
		nbc.write((short)packetType);
		nbc.markWritePosition();
	}
	public void terminatePacket(int packetLength, INonBlockingConnection nbc) throws BufferOverflowException, IOException{
		nbc.resetToWriteMark();
		
		nbc.write((short)packetLength);
		nbc.flush();
	}
}
